package object.obj2D.graphics;

import java.io.DataInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.microedition.khronos.opengles.GL10;

import android.graphics.Bitmap;

import system.Graphics;

public class AnimSystem {
	// ------------------------------------------------------------
	// / Variable declare
	// ------------------------------------------------------------
	private int LP_FOREVER = -1;
	private int LP_NO_LOOP = LP_FOREVER + 1;
	private boolean onChange = false;
	private int k_numberOfFrame;
	private int m_beginFrame;
	private int m_endFrame;
	private int m_iLoop = LP_FOREVER;
	private int m_iCurrLoop;


	private AnimData[] m_animData;
	private long m_startTime;
	private long m_currentTime;
	private int m_currentFrame = 0;

	private int m_textureID;
	private String m_fileName;
	private String m_resourceName = "";
	private int m_imgWidth;
	private int m_imgHeight;
	private int m_texturePosition;
	private Texture m_texture = new Texture();
	public final int COLOR_ALL = m_texture.COLOR_ALL;
	public final int COLOR_RED = m_texture.COLOR_RED;
	public final int COLOR_GREEN = m_texture.COLOR_GREEN;
	public final int COLOR_BLUE = m_texture.COLOR_BLUE;
	private boolean convertColor = false;
	private int srcColor = COLOR_ALL;
	private int destColor = COLOR_GREEN;
	private GL10 gl = Graphics.GetGraphics();
	private boolean m_isAnimPlaying = true;

	// ------------------------------------------------------------
	// / Constructor
	// ------------------------------------------------------------
	public AnimSystem(String fileName, int position, int loop) {
		m_iLoop = loop;
		this.setFileName(fileName);
		this.setTexturePosition(position);
		this.Init();
	}

	public AnimSystem(String fileName, int position) {
		this.setFileName(fileName);
		this.setTexturePosition(position);
		this.Init();
	}

	public void reInit() {
		this.Init();
	}

	private void Init() {
		readFile(this.m_fileName, m_texturePosition);
		m_textureID = this.loadTexture(m_resourceName);
		for (int i = 0; i < k_numberOfFrame; i++) {
			m_animData[i].setX(m_animData[i].getX() / m_imgWidth);
			m_animData[i].setY(m_animData[i].getY() / m_imgHeight);
			m_animData[i].setWidth(m_animData[i].getWidth() / m_imgWidth);
			m_animData[i].setHeight(m_animData[i].getHeight() / m_imgHeight);
			m_animData[i].initTexBuffer();
		}
		m_beginFrame = 0;
		m_endFrame = k_numberOfFrame - 1;
		gl.glEnable(GL10.GL_BLEND);
		gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
	}

	// ------------------------------------------------------------
	// / Render
	// ------------------------------------------------------------
	public void Render() {
		if (!onChange) {
			m_isAnimPlaying = true;
		}
		gl.glEnable(GL10.GL_TEXTURE_2D);
		gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		gl.glBindTexture(GL10.GL_TEXTURE_2D, m_textureID);
		this.getAnimationPlay();
		gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0,
				m_animData[m_currentFrame].getTexBuffer());
	}

	public void playFrame(int iFrame) {
		gl.glEnable(GL10.GL_TEXTURE_2D);
		gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		gl.glBindTexture(GL10.GL_TEXTURE_2D, m_textureID);
		gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0,
				m_animData[iFrame].getTexBuffer());
	}

	public int loadTexture(String resName) {
		int textureID;
		if (convertColor) {
			Bitmap bitmap = m_texture.loadBitmap(resName);
			bitmap = m_texture.ConvertColor(bitmap, srcColor, destColor);
			textureID = m_texture.initTexture(bitmap);
		} else {
			textureID = m_texture.initTexture(resName);
		}
		this.m_imgWidth = m_texture.getWidth();
		this.m_imgHeight = m_texture.getHeight();
		return textureID;
	}

	// ------------------------------------------------------------
	// / ConvertColor
	// ------------------------------------------------------------
	public void ConverColor(int srcColor, int destColor) {

	}

	// ------------------------------------------------------------
	// / Read data from binary file
	// ------------------------------------------------------------
	private void readFile(String fileName, int position) {
		DataInputStream in;
		try {
			in = new DataInputStream(getClass().getResourceAsStream(fileName));
			int numOfAnim = in.readInt();
			int translate = 0;
			for (int i = 0; i < numOfAnim; i++) {
				if (i == position)
					translate = in.readInt();
				else
					in.readInt();
			}
			// move the pointer
			if (translate > 0) {
				byte[] buffer = new byte[translate];
				in.read(buffer);
			}

			int n = in.readInt();
			for (int i = 0; i < n; i++) {
				char c = in.readChar();
				m_resourceName += c;
			}
			k_numberOfFrame = in.readInt();
			m_animData = new AnimData[k_numberOfFrame];
			for (int i = 0; i < k_numberOfFrame; i++) {
				m_animData[i] = new AnimData();
				m_animData[i].setX(in.readFloat());
				m_animData[i].setY(in.readFloat());
				m_animData[i].setWidth(in.readFloat());
				m_animData[i].setHeight(in.readFloat());
				m_animData[i].setTimeToLive(in.readLong());
			}
			in.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// ------------------------------------------------------------
	// / Select animation to play
	// ------------------------------------------------------------
	private void getAnimationPlay() {
		if (m_isAnimPlaying) {
			if (!onChange) {
				onChange = true;
				m_startTime = System.currentTimeMillis();
			}
			m_currentTime = System.currentTimeMillis();
			if (m_currentTime - m_startTime >= m_animData[m_currentFrame]
					.getTimeToLive()) {
				m_startTime = System.currentTimeMillis();
				m_currentFrame++;
				if (m_currentFrame > m_endFrame) {
					m_currentFrame = m_endFrame;
					if (m_iCurrLoop != LP_FOREVER) {
						if (m_iCurrLoop == LP_NO_LOOP) {
							m_isAnimPlaying = false;
						} else {
							m_currentFrame = m_beginFrame;
							--m_iCurrLoop;
						}
					} else
						m_currentFrame = m_beginFrame;
				}
			}
		}
	}

	// ------------------------------------------------------------
	// / Check animation is playing or stop
	// ------------------------------------------------------------
	public boolean isAnimPlaying() {
		return m_isAnimPlaying;
	}

	// ------------------------------------------------------------
	// / Getter and setter function
	// ------------------------------------------------------------
	public void setFileName(String m_fileName) {
		this.m_fileName = m_fileName;
	}

	public String getFileName() {
		return m_fileName;
	}

	public void setTexturePosition(int m_texturePosition) {
		this.m_texturePosition = m_texturePosition;
	}

	public int getTexturePosition() {
		return m_texturePosition;
	}

	public void setPlayFrame(int playFrame) {
		this.m_currentFrame = playFrame;
	}

	public int getPlayFrame() {
		return this.m_currentFrame;
	}

	public void setBeginFrame(int m_beginFrame) {
		this.m_beginFrame = m_beginFrame;
	}

	public int getBeginFrame() {
		return m_beginFrame;
	}

	public void setEndFrame(int m_endFrame) {
		this.m_endFrame = m_endFrame;
	}

	public int getEndFrame() {
		return m_endFrame;
	}

	public void setLoop(int m_iLoop) {
		this.m_iLoop = m_iLoop;
	}

	public void Play() {
		this.LoadIdentity();
		this.m_isAnimPlaying = true;
	}

	public void Stop() {
		this.m_isAnimPlaying = false;
	}

	public int getNumberOfFrame() {
		return k_numberOfFrame;
	}

	public void LoadIdentity() {
		onChange = false;
		this.m_iCurrLoop = m_iLoop;
		this.setPlayFrame(this.getBeginFrame());
	}

	public void setSrcColor(int srcColor) {
		this.srcColor = srcColor;
	}

	public int getSrcColor() {
		return srcColor;
	}

	public void setDestColor(int destColor) {
		this.destColor = destColor;
	}

	public int getDestColor() {
		return destColor;
	}

	public void setConvertColor(boolean convertColor) {
		this.convertColor = convertColor;
		m_textureID = this.loadTexture(m_resourceName);
	}

}
